/*Copyright (C) 2013-2022 LZE*/
#include<bits/stdc++.h>
#define fo(x) freopen(#x".in","r",stdin); freopen(#x".out","w",stdout);
#define INF 0x7fffffff
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int N = 1000010;
const int M = 1000010;
ll T,n,m;
struct GraphEdge{
    ll to,next,w;
    GraphEdge() {}
}edge[M];
ll head[N] = {0},cnt = 0;
void add(ll u,ll v){
    edge[++cnt].to = v;
    edge[cnt].next = head[u];
    head[u] = cnt;
}
ll dfn[N] = {0},low[N] = {0};
ll time_ = 0;
bool vis[N] = {0},instack[N] = {0};
stack<ll> GraphNode;
ll sc = 0;
ll SCC[N] = {0};
ll SCCsize[N] = {0};
ll NodeSize[N] = {0};
void Tarjan(const ll &step){
    low[step] = dfn[step] = ++time_;
    vis[step] = true;
    ll t;
    GraphNode.push(step); instack[GraphNode.top()] = true;
    for(ll i = head[step];i;i = edge[i].next){
        t = edge[i].to;
        if(!vis[t]){
            Tarjan(t);
            low[step] = min(low[step],low[t]);
        }
        else if(instack[t]) low[step] = min(low[step],low[t]);
    }
    if(dfn[step] == low[step]){
        sc++;
        while(GraphNode.top() != step){
            SCC[GraphNode.top()] = sc;
            SCCsize[sc] += NodeSize[GraphNode.top()];
            instack[GraphNode.top()] = false;
            GraphNode.pop();
        };
        SCC[GraphNode.top()] = sc;
        SCCsize[sc] += NodeSize[GraphNode.top()];
        instack[GraphNode.top()] = false;
        GraphNode.pop();
    }
}
GraphEdge edge_sp[M];
ll head_sp[N],cnt_sp = 0;
void add_sp(ll u,ll v){
    edge_sp[++cnt_sp].to = v;
    edge_sp[cnt_sp].next = head_sp[u];
    head_sp[u] = cnt_sp;
}
queue<ll> q;
ll dis[N] = {0},ans = 0;
bool used[N] = {0};
void spfa(const ll &s){
    while(!q.empty()) q.pop();
    q.push(s);
    dis[s] = max(dis[s],SCCsize[s]);
    used[s] = true;
    ll p,t;
    while(!q.empty()){
        p = q.front(); q.pop();
        used[p] = false;
        for(ll i = head_sp[p];i;i = edge_sp[i].next){
            t = edge_sp[i].to;
            if(dis[t] < dis[p] + SCCsize[t]){
                dis[t] = dis[p] + SCCsize[t];
                if(!used[t]){
                    used[t] = true;
                    q.push(t);
                }
            }
        }
    }
    for(ll i = 1;i <= n;i++) ans = max(ans,dis[i]);
}
int main() {
    scanf("%lld%lld",&n,&m);
    for(ll i = 1;i <= n;i++){
        scanf("%lld",&NodeSize[i]);
    }
    ll u,v;
    for(ll i = 1;i <= m;i++){
        scanf("%lld%lld",&u,&v);
        add(u,v);
    }
    for(ll i = 1;i <= n;i++)
        if(!vis[i]) Tarjan(i);
    for(ll i = 1;i <= n;i++)
        for(ll j = head[i];j;j = edge[j].next)
            if(SCC[i] != SCC[edge[j].to])
                add_sp(SCC[i],SCC[edge[j].to]);
    for(ll i = 1;i <= n;i++) spfa(i);
    cout << ans << endl;
    return 0;
}
